package cz.muni.fi.pb138;

/**
 *
 * @author Simon
 */
 

import cz.muni.fi.pb138.db.FindXml;
import cz.muni.fi.pb138.db.PDFfromLatexBuilder;
import cz.muni.fi.pb138.db.PutXml;
import cz.muni.fi.pb138.db.XSLTProcessor;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpSession;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPathExpressionException;
import org.xml.sax.SAXException;

@WebServlet(BiographyServlet.URL_MAPPING + "/*")
public class BiographyServlet extends HttpServlet {
 
    private static final String INDEX_JSP = "/index.jsp";
    public static final String URL_MAPPING = "/biography";
    private static final String MIKTEX_PATH = "C:\\Program Files (x86)\\MiKTeX 2.9\\miktex\\bin\\";
    public static final String PROJECT_PATH = "D:\\Ucebne materialy - stvrty semester\\Moderni_znackovaci_jazyky\\Projekt\\BiographyApp";
  
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        showBiographyFormular(request, response);
    }
 
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //aby fungovala čeština z formulára
        request.setCharacterEncoding("utf-8");
        //akcia podľa prípony v URL
        String action = request.getPathInfo();
        AuthTest authTest;
        
        //autentizácia užívateľa, aby sme mohli pristupovať k ID užívateľa
        try {
            authTest = new AuthTest();
        } catch (SAXException | ParserConfigurationException e) {
            throw new ServletException(e);
        }
 
          if (action.equals("/register")) {
                //načítanie POST parametrov z formulára
                String usernamesignup = request.getParameter("usernamesignup");
                String passwordsignup = request.getParameter("passwordsignup");
                String passwordsignup_confirm = request.getParameter("passwordsignup_confirm");

                //kontrola vyplnenia hodnôt
                if (usernamesignup == null || usernamesignup.length() == 0 ||
                        passwordsignup == null || passwordsignup.length() == 0 || passwordsignup_confirm == null || passwordsignup_confirm.length() == 0) {
                    request.setAttribute("chyba", "Je nutné vyplnit všechny hodnoty !");
                    return;
                }
                if (!passwordsignup.equals(passwordsignup_confirm)) {
                    request.setAttribute("chyba", "Zadané heslá se musí shodovat !");
                    showBiographyFormular(request, response);
                    return;             
                }
                if (authTest.hasSameName(usernamesignup)) {
                    request.setAttribute("chyba", "Užívateľské meno už existuje, vyberte prosím iné.");
                    showBiographyFormular(request, response);
                    return;             
                }
                //redirect-after-POST je ochrana pred viacnásobným odosláním formulára
                response.sendRedirect(request.getContextPath()+URL_MAPPING);
                //response.sendRedirect(request.getContextPath());
                
                //spracovanie dát- uloženie užívateľa do xml súboru
                try {
                    authTest.addUser(usernamesignup, passwordsignup);
                } catch (TransformerException | XPathExpressionException e) {
                    throw new ServletException(e);
                }
               
        } else {
              if (action.equals("/createBiography")) {
                  
                    StringWriter sw = null;
                    BufferedWriter bw = null;
                    
                    BiographyLoginModule pomModule = new BiographyLoginModule();
                    Integer userID = pomModule.getUserID();
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss") ;
                    
                    Date date = new Date();
                    
                    try{
                       sw = new StringWriter();

                       bw = new BufferedWriter(sw);
                     
                       //zapisovanie životopisu
                       bw.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n");
                       
                       bw.write("<cvFile " + "userID=\"" + userID + "\" date=\"" + dateFormat.format(date) + "\">\n");
                       
                       bw.write("<cv>\n");
                       
                       bw.write("<beforeNameAcademicTitle>");
                       bw.write(request.getParameter("beforeNameAcademicTitles"));
                       bw.write("</beforeNameAcademicTitle>\n");

                       bw.write("<firstName>");
                       bw.write(request.getParameter("firstName"));
                       bw.write("</firstName>\n");
                       
                       bw.write("<lastName>");
                       bw.write(request.getParameter("lastName"));
                       bw.write("</lastName>\n");
                       
                       bw.write("<afterNameAcademicTitle>");
                       bw.write(request.getParameter("afterNameAcademicTitles"));
                       bw.write("</afterNameAcademicTitle>\n");
                       
                       bw.write("<dayOfBirth>");
                       bw.write(request.getParameter("dayOfBirth"));
                       bw.write("</dayOfBirth>\n");
                       
                       bw.write("<phoneNumbers>\n");
                            String[] phoneNumbers = request.getParameter("phoneNumbers").split(",");
                            for (int i = 0; i < phoneNumbers.length; i++) {
                                 bw.write("<phoneNumber>");
                                 bw.write(phoneNumbers[i].trim());
                                 bw.write("</phoneNumber>\n");
                            }
                       bw.write("</phoneNumbers>\n");
                       
                       bw.write("<emails>\n");
                            String[] emails = request.getParameter("emails").split(",");
                            for (int i = 0; i < emails.length; i++) {
                                 bw.write("<email>");
                                 bw.write(emails[i].trim());
                                 bw.write("</email>\n");
                            }
                       bw.write("</emails>\n");
                       
                       bw.write("<address>\n");
                            bw.write("<street>");
                            bw.write(request.getParameter("street"));
                            bw.write("</street>\n");
                            bw.write("<city>");
                            bw.write(request.getParameter("city"));
                            bw.write("</city>\n");
                            bw.write("<postcode>");
                            bw.write(request.getParameter("postcode"));
                            bw.write("</postcode>\n");
                       bw.write("</address>\n");

                       bw.write("<educations>\n");

                            bw.write("<education>\n");

                                bw.write("<name>");
                                bw.write(request.getParameter("schoolName"));
                                bw.write("</name>\n");

                                if (request.getParameter("subjectOfStudy") != null) {
                                    bw.write("<subjectOfStudy>");
                                    bw.write(request.getParameter("subjectOfStudy"));
                                    bw.write("</subjectOfStudy>\n");
                                }
                                
                                bw.write("<from>");
                                bw.write(request.getParameter("studiedFrom"));
                                bw.write("</from>\n");
                                
                                if (request.getParameter("studiedTo") != null) {
                                    bw.write("<to>");
                                    bw.write(request.getParameter("studiedTo"));
                                    bw.write("</to>\n");
                                }
                                
                                bw.write("<note>");
                                bw.write(request.getParameter("schoolNote"));
                                bw.write("</note>\n");
                                
                            bw.write("</education>\n");

                            
                            // for multiple educations, see JavaScript in cvFields.jsp
                            for (int i = 1; request.getParameter("schoolName" + i) != null; i++) {
                                bw.write("<education>\n");

                                    bw.write("<name>");
                                    bw.write(request.getParameter("schoolName" + i));
                                    bw.write("</name>\n");

                                    if (request.getParameter("subjectOfStudy" + i) != null) {
                                        bw.write("<subjectOfStudy>");
                                        bw.write(request.getParameter("subjectOfStudy" + i));
                                        bw.write("</subjectOfStudy>\n");
                                    }

                                    bw.write("<from>");
                                    bw.write(request.getParameter("studiedFrom" + i));
                                    bw.write("</from>\n");

                                    if (request.getParameter("studiedTo" + i) != null) {
                                        bw.write("<to>");
                                        bw.write(request.getParameter("studiedTo" + i));
                                        bw.write("</to>\n");
                                    }
                                    
                                    if (request.getParameter("employmentNote" + i) != null) {                                    
                                        bw.write("<note>");
                                        bw.write(request.getParameter("schoolNote" + i));
                                        bw.write("</note>\n");
                                    }
                                
                                bw.write("</education>\n");
                           }
                       bw.write("</educations>\n");
                       
                       
                       bw.write("<employments>\n");

                            bw.write("<employment>\n");

                                bw.write("<name>");
                                bw.write(request.getParameter("employmentName"));
                                bw.write("</name>\n");

                                bw.write("<position>");
                                bw.write(request.getParameter("employmentPosition"));
                                bw.write("</position>\n");
                                
                                bw.write("<from>");
                                bw.write(request.getParameter("employmentFrom"));
                                bw.write("</from>\n");
                                
                                if (request.getParameter("employmentTo") != null) {
                                    bw.write("<to>");
                                    bw.write(request.getParameter("employmentTo"));
                                    bw.write("</to>\n");
                                }
                                if (request.getParameter("employmentNote") != null) {
                                    bw.write("<note>");
                                    bw.write(request.getParameter("employmentNote"));
                                    bw.write("</note>\n");
                                }
                            bw.write("</employment>\n");

                            
                            // for multiple educations, see JavaScript in cvFields.jsp
                            for (int j = 1; request.getParameter("employmentName" + j) != null; j++) {
                                bw.write("<employment>\n");

                                bw.write("<name>");
                                bw.write(request.getParameter("employmentName" + j));
                                bw.write("</name>\n");

                                bw.write("<position>");
                                bw.write(request.getParameter("employmentPosition" + j));
                                bw.write("</position>\n");
                                
                                bw.write("<from>");
                                bw.write(request.getParameter("employmentFrom" + j));
                                bw.write("</from>\n");
                                
                                if (request.getParameter("employmentTo" + j) != null) {
                                    bw.write("<to>");
                                    bw.write(request.getParameter("employmentTo" + j));
                                    bw.write("</to>\n");
                                }
                                if (request.getParameter("employmentNote" + j) != null) {
                                    bw.write("<note>");
                                    bw.write(request.getParameter("employmentNote" + j));
                                    bw.write("</note>\n");
                                }
                                bw.write("</employment>\n");
                           }
                       bw.write("</employments>\n");                    
                       
                       
                       bw.write("<languages>\n");
                       for (int i = 1; i<=5; i++) {
                           if (!request.getParameter("language" + i).equals("prázdny") && !request.getParameter("level" + i).equals("prázdny")) {
                               bw.write("<language>\n");
                               bw.write("<name>");
                               bw.write(request.getParameter("language" + i));
                               bw.write("</name>\n");
                               
                               bw.write("<level>");
                               bw.write(request.getParameter("level" + i));                               
                               bw.write("</level>\n");
                               bw.write("</language>\n");
                           }
                       }
                       bw.write("</languages>\n");
                       
                       
                      bw.write("<skills>\n");

                            bw.write("<skill>");
                            bw.write(request.getParameter("skill"));
                            bw.write("</skill>\n");
                            
                            // for multiple educations, see JavaScript in cvFields.jsp
                            for (int j = 1; request.getParameter("skill" + j) != null; j++) {
                                bw.write("<skill>");
                                bw.write(request.getParameter("skill" + j));
                                bw.write("</skill>\n");
                           }
                       bw.write("</skills>\n");     
                       
                       bw.write("<hobbies>\n");

                            bw.write("<hobby>");
                            bw.write(request.getParameter("hobby"));
                            bw.write("</hobby>\n");
                            
                            // for multiple educations, see JavaScript in cvFields.jsp
                            for (int j = 1; request.getParameter("hobby" + j) != null; j++) {
                                bw.write("<hobby>");
                                bw.write(request.getParameter("hobby" + j));
                                bw.write("</hobby>\n");
                           }
                       bw.write("</hobbies>\n");
                          
                       bw.write("</cv>\n");
                       
                       bw.write("</cvFile>");
                       
                       bw.flush();

                       StringBuffer sb = sw.getBuffer();
                       
                       
                       //vypisovanie do suboru
                       String fileName = PROJECT_PATH + "\\cv"+ userID + dateFormat.format(date) + ".txt";     
                       File file = new File(fileName);
                       BufferedWriter out = new BufferedWriter(new FileWriter(file));
                       out.write(sb.toString());
                       out.flush();
                       out.close();
                      // System.out.println(sb);
                       
                       //volanie metódy na uloženie do databázy
                       if (PutXml.putXml(file) != 0) {
                            Logger.getLogger(BiographyServlet.class.getName()).log(Level.SEVERE, null, "Failed to store XML.");
                       }

                    }catch(IOException e){
                       e.printStackTrace();
                    } catch (Exception ex) {
                      Logger.getLogger(BiographyServlet.class.getName()).log(Level.SEVERE, null, ex);
                  }finally{
                       // releases any system resources associated with the stream
                       if(sw!=null)
                          sw.close();
                       if(bw!=null)
                          bw.close();
                    } 
                    response.sendRedirect(request.getContextPath()+"/ManageBiographiesServlet");
              }
              else {
                  if (action.equals("/generatePDF")) {
                      BiographyLoginModule pomModule = new BiographyLoginModule();
                      Integer userID = pomModule.getUserID();
                      
                      try {
                          String selectedCV = request.getParameter("selectedCV");
                          String cv = FindXml.findCV(userID, selectedCV);
                          System.out.println("Selected CV - content: " + cv);
                          XSLTProcessor proc = new XSLTProcessor();
                          proc.generate(cv);
                          PDFfromLatexBuilder pflb = new PDFfromLatexBuilder(MIKTEX_PATH);
                          System.out.println(pflb.createPDF(new File(PROJECT_PATH + "\\src\\java\\cz\\muni\\fi\\pb138\\db\\cv")));
                          
                      } catch (Exception ex) {
                          Logger.getLogger(BiographyServlet.class.getName()).log(Level.SEVERE, null, ex);
                      }
                  }
                  else {
                      if (action.equals("/logout")) {
                          HttpSession session = request.getSession(false);
                          if(session != null) {
                              session.invalidate();
                          }
                          request.getRequestDispatcher(INDEX_JSP).forward(request, response);
                          return;
                      }
                      else {
                          response.sendError(HttpServletResponse.SC_NOT_FOUND, "Unknown action " + action);
                      }
                  }
                  response.sendRedirect(request.getContextPath()+"/ManageBiographiesServlet");
              }
        }
    }
    
   
    private void showBiographyFormular(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            
            request.getRequestDispatcher(INDEX_JSP).forward(request, response);
    }
}